package samber

import (
	"fmt"
	"github.com/samber/lo"
	"time"
)

// Assign merges multiple maps from left to right
// 从第一个挨个拆出来 重复的话以最新的为准
func Assign() {
	result := lo.Assign(
		map[string]int{"a": 1, "b": 2},
		map[string]int{"b": 3, "c": 4},
	)
	fmt.Printf("%v\n", result) // map[a:1 b:3 c:4]
}

// Associate 对于数组可以二次处理形成对应的Map
func Associate() {
	list := []string{"a", "aa", "aaa"}

	result := lo.Associate(list, func(str string) (string, int) {
		return str, len(str)
	})

	fmt.Printf("%v\n", result) // map[a:1 aa:2 aaa:3]
}

// Attempt 尝试调用函数N次，直到返回有效输出
// 从0开始 如果是错误 那么继续迭下一轮 直到返回为 nil count为走了多少轮(1 开始)
func Attempt() {
	count, err := lo.Attempt(10, func(i int) error {
		fmt.Println(i)
		if i < 3 {
			return fmt.Errorf("error")
		} else {
			return nil
		}
	})
	fmt.Printf("%v %v\n", count, err) // 4 nil
}

// AttemptWhile 如果第二个bool值返回false值，它将立即终止调用
func AttemptWhile() {
	count, err := lo.AttemptWhile(10, func(i int) (error, bool) {
		fmt.Println(i)
		if i < 3 {
			return fmt.Errorf("error"), false // 为false不继续了 是错误就是错误
		} else {
			return nil, true
		}
	})
	fmt.Printf("%v %v\n", count, err) // 1 error
}

// AttemptWhileWithDelay 多了个每次调用之间都有暂停
func AttemptWhileWithDelay() {
	start := time.Now().Unix()
	count, duration, err := lo.AttemptWhileWithDelay(10, 2*time.Second, func(i int, duration time.Duration) (error, bool) {
		now := time.Now().Unix()
		fmt.Println(now - start)
		if i < 2 {
			return fmt.Errorf("error but go"), true
		} else {
			return fmt.Errorf("error"), false // 为false不继续了 是错误就是错误
		}
	})

	// duration 为总共用了多久时间
	fmt.Printf("%v %v %v\n", count, duration, err) // 4 6.00244005s error
}

// AttemptWithDelay Attempt 上加了暂停
func AttemptWithDelay() {
	fmt.Println("AttemptWithDelay 就是在 Attempt 加了暂停")
}
